﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Modularity;
using Volo.Abp.Testing;
using Volo.Abp.Uow;

namespace Sample.Novel.TestBase
{
    public abstract class NovelTestBase<TStartupModule>
        :AbpIntegratedTest<TStartupModule>
        where TStartupModule : IAbpModule
    {
        protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
        {
            options.UseAutofac();
        }

        protected virtual async Task WithUntiOfWorkAsync(AbpUnitOfWorkOptions options,Func<Task> action) {
            using (var scope = ServiceProvider.CreateScope()) {
                var uowManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
                using (var uow = uowManager.Begin(options))
                {
                    await action();
                    await uow.CompleteAsync();
                }
            }
        }

        protected virtual async Task<TResult> WithUntiOfWorkAsync<TResult>(AbpUnitOfWorkOptions options,Func<Task<TResult>> func) {
            using (var scope = ServiceProvider.CreateScope()) { 
                var uowManager = scope.ServiceProvider.GetRequiredService<IUnitOfWorkManager>();
                using (var uow = uowManager.Begin(options))
                {
                    var result = await func();
                    await uow.CompleteAsync();
                    return result;
                }
            }
        }

        protected virtual Task WithUntiOfWorkAsync(Func<Task> action) {
            return WithUntiOfWorkAsync(new AbpUnitOfWorkOptions(), action);
        }

        protected virtual Task<TResult> WithUntiOfWorkAsync<TResult>(Func<Task<TResult>> func) {
            return WithUntiOfWorkAsync<TResult>(new AbpUnitOfWorkOptions(), func);
        }
    }
}
